# Copyright 2012 The Rust Project Developers. See the COPYRIGHT
# file at the top-level directory of this distribution and at
# http://rust-lang.org/COPYRIGHT.
#
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.

# <help> \(^o^)/
#
# Greetings, adventurer! The Rust Build System is at your service.
#
# Whether you want a genuine copy of `rustc`, access to the latest and
# most authoritative Rust documentation, or even to investigate the
# most intimate workings of the compiler itself, you've come to the
# right place. Let's see what's on the menu.
#
# First, start with one of these build targets:
#
#   * all - The default. Build a complete, bootstrapped compiler.
#           `rustc` will be in `${target-triple}/stage2/bin/`. Run it
#           directly from the build directory if you like. This also
#           comes with docs in `doc/`.
#
#   * check - Run the complete test suite
#
#   * clean - Clean the build repository. It is advised to run this
#             command if you want to build Rust again, after an update
#             of the git repository.
#
#   * install - Install Rust. Note that installation is not necessary
#               to use the compiler.
#
#   * uninstall - Uninstall the binaries
#
# For tips on working with The Rust Build System, just:
#
#     run `make tips`
#
# Otherwise
#
#     run `make`
#
# </help>
#
# <tips>
#
# # The Rust Build System Tip Line
#
# There are a bazillion different targets you might want to build. Here
# are a few ideas.
#
#   * docs - Build gobs of HTML documentation and put it into `doc/`
#   * check-$(crate) - Test a crate, e.g. `check-std`
#   * check-ref - Run the language reference tests
#   * check-docs - Test the documentation examples
#   * check-stage$(stage)-$(crate) - Test a crate in a specific stage
#   * check-stage$(stage)-{rpass,rfail,cfail,rmake,...} - Run tests in src/test/
#   * check-stage1-T-$(target)-H-$(host) - Run cross-compiled-tests
#   * tidy - Basic style check, show highest rustc error code and
#     the status of language and lib features
#   * rustc-stage$(stage) - Only build up to a specific stage
#   * $host/stage1/bin/rustc - Only build stage1 rustc, not libstd. For further
#     information see "Rust recipes for build system success" below.
#
# Then mix in some of these environment variables to harness the
# ultimate power of The Rust Build System.
#
#   * `VERBOSE=1` - Print all commands. Use this to see what's going on.
#   * `RUSTFLAGS=...` - Add compiler flags to all `rustc` invocations
#   * `JEMALLOC_FLAGS=...` - Pass flags to jemalloc's configure script
#
#   * `TESTNAME=...` - Specify the name of tests to run
#   * `CHECK_IGNORED=1` - Run normally-ignored tests
#   * `PLEASE_BENCH=1` - Run crate benchmarks (enable `--bench` flag)
#
#   * `CFG_ENABLE_VALGRIND=1` - Run tests under valgrind
#   * `VALGRIND_COMPILE=1` - Run the compiler itself under valgrind
#                            (requires `CFG_ENABLE_VALGRIND`)
#
#   * `NO_REBUILD=1` - Don't rebootstrap when testing std
#                      (and possibly other crates)
#   * `NO_MKFILE_DEPS=1` - Don't rebuild for modified .mk files
#
#   * `SAVE_TEMPS=1` - Use `--save-temps` flag on all `rustc` invocations
#   * `ASM_COMMENTS=1` - Use `-Z asm-comments`
#   * `TIME_PASSES=1` - Use `-Z time-passes`
#   * `TIME_LLVM_PASSES=1` - Use `-Z time-llvm-passes`
#   * `TRACE=1` - Use `-Z trace`
#
# # Rust recipes for build system success
#
#     // Modifying libstd? Use this command to run unit tests just on your change
#     make check-stage1-std NO_REBUILD=1 NO_BENCH=1
#
#     // Modifying just rustc?
#     // Compile rustc+libstd once
#     make rustc-stage1
#     // From now on use this command to rebuild just rustc and reuse the previously built libstd
#     // $host is a target triple, eg. x86_64-unknown-linux-gnu
#     // The resulting binary is located at $host/stage1/bin/rustc.
#     // If there are any issues with libstd recompile it with the command above.
#     make $host/stage1/bin/rustc
#
#     // Added a run-pass test? Use this to test running your test
#     make check-stage1-rpass TESTNAME=my-shiny-new-test
#
#     // Having trouble figuring out which test is failing? Turn off parallel tests
#     make check-stage1-std RUST_TEST_THREADS=1
#
#     // To make debug!() and other logging calls visible, reconfigure:
#     ./configure --enable-debug-assertions
#     make ....
#
# If you really feel like getting your hands dirty, then:
#
#     run `make nitty-gritty`
#
# # Make command examples
#
# ## Docs linked commands
#
# * make check-stage1-rustdocck: Builds rustdoc. It has the advantage to compile
#                                quite quickly since we're only using stage1
#                                executables.
# * make doc/error-index.md: Gets all doc blocks from doc comments and error
#                            explanations to put them in a markdown file. You
#                            can then test them by running
#                            "rustdoc --test error-index.md".
#
# And of course, the wonderfully useful 'make tidy'! Always run it before opening a pull request to rust!
#
# </tips>
#
# <nitty-gritty>
#
# # The Rust Build System
#
# Gosh I wish there was something useful here (TODO).
#
# # An (old) explanation of how the build is structured:
#
# *Note: Hey, like, this is probably inaccurate, and is definitely
# an outdated and insufficient explanation of the remarkable
# Rust Build System.*
#
# There are multiple build stages (0-3) needed to verify that the
# compiler is properly self-hosting. Each stage is divided between
# 'host' artifacts and 'target' artifacts, where the stageN host
# compiler builds artifacts for 1 or more stageN target architectures.
# Once the stageN target compiler has been built for the host
# architecture it is promoted (copied) to a stageN+1 host artifact.
#
# The stage3 host compiler is a compiler that successfully builds
# itself and should (in theory) be bitwise identical to the stage2
# host compiler. The process is bootstrapped using a stage0 host
# compiler downloaded from a previous snapshot.
#
# At no time should stageN artifacts be interacting with artifacts
# from other stages. For consistency, we use the 'promotion' logic
# for all artifacts, even those that don't make sense on non-host
# architectures.
#
# The directory layout for a stage is intended to match the layout
# of the installed compiler, and looks like the following:
#
# stageN - this is the system root, corresponding to, e.g. /usr
#   bin - binaries compiled for the host
#   lib - libraries used by the host compiler
#     rustlib - rustc's own place to organize libraries
#       $(target) - target-specific artifacts
#         bin - binaries for target architectures
#         lib - libraries for target architectures
#
# A note about host libraries:
#
# The only libraries that get promoted to stageN/lib are those needed
# by rustc. In general, rust programs, even those compiled for the
# host architecture will use libraries from the target
# directories. This gives rust some freedom to experiment with how
# libraries are managed and versioned without polluting the common
# areas of the filesystem.
#
# General rust binaries may still live in the host bin directory; they
# will just link against the libraries in the target lib directory.
#
# Admittedly this is a little convoluted.
#
# If you find yourself working on the make infrastructure itself, and trying to
# find the value of a given variable after expansion, you can use:
#
# make print-VARIABLE_NAME
#
# To extract it
#
# </nitty-gritty>
#

######################################################################
# Primary rules
######################################################################

# Issue #9531: If you change the order of any of the following (or add
# new definitions), make sure definitions always precede their uses,
# especially for the dependency lists of recipes.

# First, load the variables exported by the configure script
include config.mk

# Just a few macros used everywhere
include $(CFG_SRC_DIR)mk/util.mk
# Reconfiguring when the makefiles or submodules change
include $(CFG_SRC_DIR)mk/reconfig.mk
# All crates and their dependencies
include $(CFG_SRC_DIR)mk/crates.mk
# Various bits of setup, common macros, and top-level rules
include $(CFG_SRC_DIR)mk/main.mk
# C and assembly components that are not LLVM
include $(CFG_SRC_DIR)mk/rt.mk
# Rules for crates in the target directories
include $(CFG_SRC_DIR)mk/target.mk
# Rules for crates in the host directories
include $(CFG_SRC_DIR)mk/host.mk
# Special rules for bootstrapping stage0
include $(CFG_SRC_DIR)mk/stage0.mk
# Rust-specific LLVM extensions
include $(CFG_SRC_DIR)mk/rustllvm.mk
# Documentation
include $(CFG_SRC_DIR)mk/docs.mk
# LLVM
include $(CFG_SRC_DIR)mk/llvm.mk
# Rules for installing debugger scripts
include $(CFG_SRC_DIR)mk/debuggers.mk

######################################################################
# Secondary makefiles, conditionalized for speed
######################################################################

# The test suite
ifneq ($(strip $(findstring check,$(MAKECMDGOALS)) \
               $(findstring test,$(MAKECMDGOALS))  \
               $(findstring tidy,$(MAKECMDGOALS))),)
  CFG_INFO := $(info cfg: including test rules)
  include $(CFG_SRC_DIR)mk/tests.mk
  include $(CFG_SRC_DIR)mk/grammar.mk
endif

# Copy all the distributables to another directory for binary install
ifneq ($(strip $(findstring prepare,$(MAKECMDGOALS)) \
               $(findstring dist,$(MAKECMDGOALS)) \
               $(findstring install,$(MAKECMDGOALS))),)
  CFG_INFO := $(info cfg: including prepare rules)
  include $(CFG_SRC_DIR)mk/prepare.mk
endif

# Source and binary distribution artifacts
ifneq ($(strip $(findstring dist,$(MAKECMDGOALS)) \
               $(findstring install,$(MAKECMDGOALS)) \
               $(findstring clean,$(MAKECMDGOALS))),)
  CFG_INFO := $(info cfg: including dist rules)
  include $(CFG_SRC_DIR)mk/dist.mk
endif

# (Unix) Installation from the build directory
ifneq ($(findstring install,$(MAKECMDGOALS)),)
  CFG_INFO := $(info cfg: including install rules)
  include $(CFG_SRC_DIR)mk/install.mk
endif

# Cleaning
ifneq ($(findstring clean,$(MAKECMDGOALS)),)
  CFG_INFO := $(info cfg: including clean rules)
  include $(CFG_SRC_DIR)mk/clean.mk
endif

# CTAGS building
ifneq ($(strip $(findstring TAGS.emacs,$(MAKECMDGOALS)) \
               $(findstring TAGS.vi,$(MAKECMDGOALS)) \
               $(findstring TAGS.rustc.emacs,$(MAKECMDGOALS)) \
               $(findstring TAGS.rustc.vi,$(MAKECMDGOALS))),)
  CFG_INFO := $(info cfg: including ctags rules)
  include $(CFG_SRC_DIR)mk/ctags.mk
endif

.DEFAULT:
	@echo
	@echo "======================================================"
	@echo "== If you need help, run 'make help' or 'make tips' =="
	@echo "======================================================"
	@echo
	exit 1
